package com.lenovo.leos.filebrowser.engine.operation;

//import j2me.io.FileNotFoundException;

//[improve] about FileUtil class

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.GZIPInputStream;
import java.util.zip.MyZipInputStream;
import java.util.zip.MyZipOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;

import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnDismissListener;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.StatFs;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

//import com.lenovo.leos.commonwidgets.PopupMenu;
import com.lenovo.leos.filebrowser.engine.util.FileClipBoard;

import com.lenovo.leos.filebrowser.engine.util.Log;
import com.lenovo.leos.filebrowser.engine.util.FileUtil;
import com.lenovo.leos.filebrowser.engine.util.MimeTypeParser;
import com.lenovo.leos.filebrowser.engine.util.MimeTypes;
import com.lenovo.leos.filebrowser.ui.Constant;
import com.lenovo.leos.filebrowser.ui.CutAndCopyVo;
import com.lenovo.leos.filebrowser.ui.FileSearcher;

import com.lenovo.leos.filebrowser.R;
//import de.innosystec.unrar.Archive;
//import de.innosystec.unrar.exception.RarException;
//import de.innosystec.unrar.rarfile.FileHeader;

public class FileCompressor extends Activity {
	private static String TAG="FileCompressor";
	
	private static final int MSG_SAMEFILE_EXISTS_ON_UNZIP_NAMEERROR = 10009;//add 2010-12-03 by xie
		
	private static final int MSG_SAMEFILE_EXISTS_ON_UNZIP = 10000;
	private static final int ZIP_NOSPACE_MSG = 20000;
	private static final int INVALID_ZIP_FILE_MSG = 30000;
	private static final int ZIP_EXCEPTION_MSG = 40000;
	private static final int UNZIP_EXCEPTION_MSG = 50000;
	private static final int MSG_RESULT_OK = 10001;
	private static final int MSG_RESULT_CANCELED = 10002;


	//for gz format file 
	private static final int MSG_SAMEFILE_EXISTS_ON_UNGZ = 60000;
	private static final int GZ_NOSPACE_MSG = 70000;
	private static final int INVALID_GZ_FILE_MSG = 80000;
	private static final int GZ_EXCEPTION_MSG = 90000;
	private static final int UNGZ_EXCEPTION_MSG = 100000;
	
	private static final int BUFF_SIZE = 1024 * 50; // 1M Byte
	
	private static FileClipBoard mfcbMarked = FileClipBoard.getInstance();
	private Bundle bundle;
	private Intent intent;
	private int requestCode = -1;
	private boolean runFlag = false;
	
	private ArrayList<String> mlNewFiles = new ArrayList<String>();

	private String rarname;
	private List<File> filelist;
	
	private File cFile;
	
	private ProgressDialog mProgress;
	
//	boolean fStop = false;
	
	private boolean mDialogHandled = false;
	private boolean zip_nospace_flag = false;
	
	//added by wuqf
	private ZipThread mThread = null;
	
	//added by guzhaohui
	
//	public  PopupMenu   compressFileDialog=null;
	private DisplayMetrics mdisplayMetric=null;
	
	private boolean mblnReplace=false;
	
	final private int DIALOG_SHOW_XSCALE=2;
	final private int DIALOG_SHOW_YSCALE=2;
	
	final private int ENTRY_DIALOG_WEIGHT=293;
	final private int ENTRY_DIALOG_HEIGHT=212;
	
	final private int ALERT_DIALOG_WEIGHT=293;
	final private int ALERT_DIALOG_HEIGHT=212;
	
	private static MimeTypes mMimeTypes = null;   //add 2010-11-25 by xie
	private boolean mNeedBroadCastFileChanged = false;    //add 2010-11-25 by xie
	private Activity instance;   //add 2010-11-25 by xie
	
//	private MyHander mMyHander=new MyHander(Looper.myLooper());
		
	/*private class MyHander extends Handler{
		
		*//**
		 * @param authorMyLooperguzhaohui
		 *//*
		public MyHander(Looper mylooper) {
			// TODO Auto-generated constructor stub
			super(mylooper);
		}
		 
		@Override
		public void handleMessage(Message message) {
			// TODO Auto-generated method stub
			//super.handleMessage(athorMsgguzhaohui);
			
			if(message.what==MY_MSG){
				Log.d(TAG, "handle message !");
				confirmCompressDialog();
				
			}
			if(message.what==EXIST_SAME_GZ_FILE){
				Log.d(TAG, "handle EXIST_SAME_GZ_FILE");
				existSameGzFile();
			}
			
		}
		
	}*/
	
	
	ZipThreadHandler mEH = new ZipThreadHandler(Looper.myLooper());
	private class ZipThreadHandler extends Handler{
		
		public ZipThreadHandler(Looper looper){
			super(looper);
		}
		
		//@Override
		public void handleMessage(final Message msg){
			
			if(msg.what == MSG_RESULT_OK ){	
				mProgress.dismiss();
				quitWithResult(RESULT_OK);			
			}else if (msg.what == MSG_RESULT_CANCELED){
				mProgress.dismiss();
				quitWithResult(RESULT_CANCELED);				
			}else if(msg.what == MSG_SAMEFILE_EXISTS_ON_UNZIP && mThread != null){
				
				// case: when to unzip, some file is existed on filesystem
				// ask user to decide whether replace or not
				mDialogHandled = false;
				
				/*mProgress.hide();
				
				TextView tvMessage=new TextView(FileCompressor.this);
				tvMessage.setText(msg.obj.toString()+"\n"+getResources().getString(R.string.override));
				
				compressFileDialog=new PopupMenu(FileCompressor.this,ALERT_DIALOG_WEIGHT,ALERT_DIALOG_HEIGHT,true,true);
				compressFileDialog.setMenuTitle(getString(R.string.remind));
				compressFileDialog.setHasDefaultTopView(true);
				compressFileDialog.setHasDefaultFootView(true);
				compressFileDialog.setOutsideTouchable(false);
				compressFileDialog.setUserContentView(tvMessage);
				
				
				compressFileDialog.getDefaultOkButton().setOnClickListener(new Button.OnClickListener() {
					public void onClick(View v) {
						// User clicked cancel so do some stuff
						mDialogHandled = true;
						mThread.mReplace = true;
						mThread.mResume = true;
						
	        			compressFileDialog.setOutsideTouchable(true);
						compressFileDialog.dismiss();
						mProgress.show();
						
						}
					
					
				});
				
				compressFileDialog.getDefaultOkButton().setText("Replace");
				
				compressFileDialog.getDefaultCancelButton().setOnClickListener(new Button.OnClickListener() {
										public void onClick(View v) {

											
										// User clicked cancel so do some stuff
											
											mDialogHandled = false;
											mThread.mReplace = false;
											//mThread.mResume = false; 
											mThread.mResume=true;
											
											
				    	        			compressFileDialog.setOutsideTouchable(true);
				    						compressFileDialog.dismiss();
										}});
				compressFileDialog.setOnDismissListener(new PopupWindow.OnDismissListener() {
					
					//@Override
					public void onDismiss() {
						// TODO Auto-generated method stub
						if(mDialogHandled == false)
		        			 mThread.toStop();
					}
				});
				compressFileDialog.showMenu(0,0,Gravity.NO_GRAVITY);
				*/

//				compressFileDialog.showMenu(mdisplayMetric.widthPixels/DIALOG_SHOW_XSCALE,mdisplayMetric.heightPixels/DIALOG_SHOW_YSCALE,Gravity.NO_GRAVITY);
				
				
				
				new AlertDialog.Builder(FileCompressor.this)
					.setTitle(R.string.remind)
					.setMessage(msg.obj.toString()+"\n"+getResources().getString(R.string.override))
					.setPositiveButton(R.string.all, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
							mDialogHandled = true;
							mThread.mReplace = true;
							mThread.mResume = true;
							mThread.mForAll = true;//add bug 80525
					}})
					.setNeutralButton(R.string.replace, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
							mDialogHandled = true;
							mThread.mReplace = true;
							mThread.mResume = true;
							mThread.mForAll = false;//add bug 80525
					}})
					.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
							mDialogHandled = false;
				    	    mThread.mReplace = false;
				    	    mThread.mResume = true;
				    	    if(mDialogHandled == false){
				    	    	mThread.toStop(); 
				    	    }
			         }})
			         .show()
			         .setOnDismissListener(new OnDismissListener(){
			        	 public void onDismiss(DialogInterface dialog) {
			        		 // TODO Auto-generated method stub
			        		 if(mDialogHandled == false)
			        			 mThread.toStop();
			        }});
				
		   }else if(msg.what == ZIP_NOSPACE_MSG){
			   // case: no enough space in filesystem
			   mDialogHandled = false;
			   zip_nospace_flag = true;
			   if(requestCode == FileOp.FOP_COMPRESS){
				   
				   
				  /* TextView tvMessage=new TextView(FileCompressor.this);
					tvMessage.setText(getString (R.string.zipnoSpace));
					
					compressFileDialog=new PopupMenu(FileCompressor.this,ALERT_DIALOG_WEIGHT,ALERT_DIALOG_HEIGHT,true,true);
					compressFileDialog.setMenuTitle(getString(R.string.remind));
					compressFileDialog.setHasDefaultTopView(true);
					compressFileDialog.setHasFootViewOnlyOk(true);
					
					compressFileDialog.setOutsideTouchable(false);
					compressFileDialog.setUserContentView(tvMessage);
					
					
					compressFileDialog.getDefaultOkButtonOnlyOk().setOnClickListener(new Button.OnClickListener() {
						public void onClick(View v) {
							// User clicked cancel so do some stuff
							mDialogHandled = true;
			   				mThread.toStop();
							
		        			compressFileDialog.setOutsideTouchable(true);
							compressFileDialog.dismiss();
							
							
							
							}
						
						
					});
					compressFileDialog.setOnDismissListener(new PopupWindow.OnDismissListener() {
						
						//@Override
						public void onDismiss() {
							// TODO Auto-generated method stub
							if(mDialogHandled == false)
			        			 mThread.toStop();
						}
					});
					compressFileDialog.showMenu(0,0,Gravity.NO_GRAVITY);
				   */
				   
				   
			   new AlertDialog.Builder(FileCompressor.this)
			   		.setTitle(R.string.remind)
			   		.setMessage(R.string.zipnoSpace)
			   		.setPositiveButton(R.string.alert_dialog_ok,new DialogInterface.OnClickListener() {
			   			public void onClick(DialogInterface dialog,int whichButton) {
			   				mDialogHandled = true;
			   				mThread.toStop();
			   				mProgress.dismiss();
			   		}})
			   		.show()
			   		.setOnDismissListener(new OnDismissListener() {
			   			public void onDismiss(DialogInterface dialog) {
			   				// TODO Auto-generated method stub
			   				if (mDialogHandled == false)
			   					mThread.toStop();
			   		}});
			   
			   }else if(requestCode == FileOp.FOP_DECOMPRESS){
				   
				   
				 /*  TextView tvMessage=new TextView(FileCompressor.this);
					tvMessage.setText(getString (R.string.unzipnoSpace));
					
					compressFileDialog=new PopupMenu(FileCompressor.this,ALERT_DIALOG_WEIGHT,ALERT_DIALOG_HEIGHT,true,true);
					compressFileDialog.setMenuTitle(getString(R.string.remind));
					compressFileDialog.setHasDefaultTopView(true);
					compressFileDialog.setHasFootViewOnlyOk(true);
					
					compressFileDialog.setOutsideTouchable(false);
					compressFileDialog.setUserContentView(tvMessage);
					
					
					compressFileDialog.getDefaultOkButtonOnlyOk().setOnClickListener(new Button.OnClickListener() {
						public void onClick(View v) {
							// User clicked cancel so do some stuff
							mDialogHandled = true;
							mThread.toStop();
							
		        			compressFileDialog.setOutsideTouchable(true);
							compressFileDialog.dismiss();
							
							}
						
						
					});
					compressFileDialog.setOnDismissListener(new PopupWindow.OnDismissListener() {
						
						//@Override
						public void onDismiss() {
							// TODO Auto-generated method stub
							if(mDialogHandled == false)
			        			 mThread.toStop();
						}
					});
					compressFileDialog.showMenu(0,0,Gravity.NO_GRAVITY);*/
					
					
				   
				   
				   if(bundle.getBoolean(FileOp.KEY_BOOLEAN_IS_ZIP)){
					   
					   new AlertDialog.Builder(FileCompressor.this)
						.setTitle(R.string.remind)
						.setMessage(R.string.unzipnoSpace)
						.setPositiveButton(R.string.alert_dialog_ok,new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
										mDialogHandled = true;
										mThread.toStop();
										mProgress.dismiss();
									}
						}).show().setOnDismissListener(new OnDismissListener() {
									public void onDismiss(DialogInterface dialog) {
										// TODO Auto-generated method stub
										if (mDialogHandled == false)
											mThread.toStop();
									}
								});
				   }else{
					   new AlertDialog.Builder(FileCompressor.this)
						.setTitle(R.string.remind)
						.setMessage(R.string.ungzipnoSpace)
						.setPositiveButton(R.string.alert_dialog_ok,new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
										mDialogHandled = true;
										mThread.toStop();
										mProgress.dismiss();
									}
						}).show().setOnDismissListener(new OnDismissListener() {
									public void onDismiss(DialogInterface dialog) {
										// TODO Auto-generated method stub
										if (mDialogHandled == false)
											mThread.toStop();
									}
								});
					   
				   }
				   
				   
				   
			   }
		   }else if(msg.what == ZIP_EXCEPTION_MSG){
			   
			   // case: zip exception 
			   mDialogHandled = false;
			   
			  /* TextView tvMessage=new TextView(FileCompressor.this);
				tvMessage.setText(getString (R.string.zipException));
				
				compressFileDialog=new PopupMenu(FileCompressor.this,ALERT_DIALOG_WEIGHT,ALERT_DIALOG_HEIGHT,true,true);
				compressFileDialog.setMenuTitle(getString(R.string.remind));
				compressFileDialog.setHasDefaultTopView(true);
				compressFileDialog.setHasFootViewOnlyOk(true);
				
				compressFileDialog.setOutsideTouchable(false);
				compressFileDialog.setUserContentView(tvMessage);
				
				
				compressFileDialog.getDefaultOkButtonOnlyOk().setOnClickListener(new Button.OnClickListener() {
					public void onClick(View v) {
						// User clicked cancel so do some stuff
						mDialogHandled = true;
						mThread.toStop();
						
	        			compressFileDialog.setOutsideTouchable(true);
						compressFileDialog.dismiss();
						
						}
					
					
				});
				compressFileDialog.setOnDismissListener(new PopupWindow.OnDismissListener() {
					
					//@Override
					public void onDismiss() {
						// TODO Auto-generated method stub
						if(mDialogHandled == false)
		        			 mThread.toStop();
					}
				});
				compressFileDialog.showMenu(0,0,Gravity.NO_GRAVITY);
				*/
			   
			   
			   new AlertDialog.Builder(FileCompressor.this)
				// .setIcon(R.drawable.alert_dialog_icon)
						.setTitle(R.string.remind)
						.setMessage(R.string.zipException)
						.setPositiveButton(R.string.alert_dialog_ok,new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,int whichButton) {
										mDialogHandled = true;
										mThread.toStop();
										mProgress.dismiss();
									}
								}).show().setOnDismissListener(new OnDismissListener(){
				                      public void onDismiss(DialogInterface dialog) {
					                  // TODO Auto-generated method stub
				                    	  if(mDialogHandled == false)
					                          mThread.toStop();
				                      }
			                        });
			   
		   }else if(msg.what == UNZIP_EXCEPTION_MSG) {

			   // case: unzip exception	
			   mDialogHandled = false;
			   
			   
			   
			  /* TextView tvMessage=new TextView(FileCompressor.this);
				tvMessage.setText(getString (R.string.unzipException));
				
				compressFileDialog=new PopupMenu(FileCompressor.this,ALERT_DIALOG_WEIGHT,ALERT_DIALOG_HEIGHT,true,true);
				compressFileDialog.setMenuTitle(getString(R.string.remind));
				compressFileDialog.setHasDefaultTopView(true);
				compressFileDialog.setHasFootViewOnlyOk(true);
				
				compressFileDialog.setOutsideTouchable(false);
				compressFileDialog.setUserContentView(tvMessage);
				
				
				compressFileDialog.getDefaultOkButtonOnlyOk().setOnClickListener(new Button.OnClickListener() {
					public void onClick(View v) {
						// User clicked cancel so do some stuff
						mDialogHandled = true;
						mThread.toStop();
						
	        			compressFileDialog.setOutsideTouchable(true);
						compressFileDialog.dismiss();
						
						}
					
					
				});
				compressFileDialog.setOnDismissListener(new PopupWindow.OnDismissListener() {
					
					//@Override
					public void onDismiss() {
						// TODO Auto-generated method stub
						if(mDialogHandled == false)
		        			 mThread.toStop();
					}
				});

				compressFileDialog.showMenu(0,0,Gravity.NO_GRAVITY);*/
				
			   
			   new AlertDialog.Builder(FileCompressor.this)
				// .setIcon(R.drawable.alert_dialog_icon)
						.setTitle(R.string.remind).setMessage(R.string.unzipException).setPositiveButton(
								R.string.alert_dialog_ok,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int whichButton) {
										mDialogHandled = true;
										mThread.toStop();
										mProgress.dismiss();
									}
								}).show().setOnDismissListener(new OnDismissListener(){
				                      public void onDismiss(DialogInterface dialog) {
					                  // TODO Auto-generated method stub
				                    	  if(mDialogHandled == false)
					                          mThread.toStop();
				                      }
			                        });
		   }else if(msg.what == INVALID_ZIP_FILE_MSG){
			   
			   // case: invalid zip file
			   mThread.toStop();
			   Toast.makeText(FileCompressor.this, R.string.invalidZipFile, Toast.LENGTH_SHORT).show();
			   mProgress.dismiss();
		   }else if(msg.what== UNGZ_EXCEPTION_MSG){
			   new AlertDialog.Builder(FileCompressor.this)
				// .setIcon(R.drawable.alert_dialog_icon)
						.setTitle(R.string.remind).setMessage(R.string.ungzipException).setPositiveButton(
								R.string.alert_dialog_ok,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int whichButton) {
										mDialogHandled = true;
										mThread.toStop();
										mProgress.dismiss();
									}
								}).show().setOnDismissListener(new OnDismissListener(){
				                      public void onDismiss(DialogInterface dialog) {
					                  // TODO Auto-generated method stub
				                    	  if(mDialogHandled == false)
					                          mThread.toStop();
				                      }
			                        });
		   }else if (msg.what==INVALID_GZ_FILE_MSG){
			   mThread.toStop();
			   Toast.makeText(FileCompressor.this, R.string.invalidGzipFile, Toast.LENGTH_SHORT).show();
			   mProgress.dismiss();
		   }
		}
	}
	
	private class ZipThread extends Thread{
		boolean mStop = false;
		boolean mResume = true;
		boolean mReplace = false;
	    private boolean mForAll = false;   //add bug 80525
		private PowerManager.WakeLock mWakeLock;
		private Context mContext;
		
		public ZipThread(Context context){
			mContext = context;
			init();
		}
		
		private void init() {
            PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
            mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
			  mForAll = false;//add bug 80525
        }
		
		@Override
		public void finalize() {
            if (mWakeLock != null && mWakeLock.isHeld()) {
                mWakeLock.release();
            }
        }

		public void toStop() {
			mResume = true;
			mStop = true;
			// fStop = true;
		}

		public boolean isStop() {
			return mStop;
		}
		 
		public void run() {
			mWakeLock.acquire();

			runFlag = true;
			File targetFile = null;
			
			switch (requestCode) {
			case FileOp.FOP_COMPRESS:
				// prepare data
				int srcfrom = bundle.getInt(FileOp.KEY_INT_SRC_FROM);  
				if ( FileOp.SRC_FROM_BUNDLE == srcfrom){//FileUtil.FROM_PATH
					filelist = new ArrayList<File>();
					String src = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH);
					if (null == src) {
						Log.e(TAG, "can not get srcfile value in bundle in thread.run");
						
						Message msg;
						msg = mEH.obtainMessage(MSG_RESULT_CANCELED, 0, 0, null);
						mEH.sendMessage(msg);	
						return;
					}else {
						File f = new File(src);
						if (null == f || !f.exists()) {
							Log.e(TAG, "the src file is invalid in thread.run");
							
							Message msg;
							msg = mEH.obtainMessage(MSG_RESULT_CANCELED, 0, 0, null);
							mEH.sendMessage(msg);	
							return;							
						} else {
							filelist.add(f);
						}
					}											
				}else if (FileOp.SRC_FROM_CLIP == srcfrom) {
					if (!mfcbMarked.hasValidData() 
							|| mfcbMarked.getOperation() != FileClipBoard.OP_COMPRESS) {
						Log.e(TAG, "there are no valid data in clip or the data is not for compress");
						Message msg;
						msg = mEH.obtainMessage(MSG_RESULT_CANCELED, 0, 0, null);
						mEH.sendMessage(msg);	
						return;		
					} else {
						filelist = mfcbMarked.getItemsInList();
					}
					
				}else {
					Log.e(TAG, "unknown srcfrom value in thread.run");
					
					Message msg;
					msg = mEH.obtainMessage(MSG_RESULT_CANCELED, 0, 0, null);
					mEH.sendMessage(msg);	
					return;
				}
									
				rarname = bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
				String toDir = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH);

				
				try {
					targetFile = new File(toDir + "/" + rarname);
					cFile = targetFile;
					zipFiles(filelist, targetFile);
				} catch (ZipException e) {
					Log.d(TAG, " catch a ZipException e");
					targetFile.delete();
					e.printStackTrace();
					Message msg = mEH.obtainMessage(ZIP_EXCEPTION_MSG, 0, 0, e
							.getMessage());
					mEH.sendMessage(msg);
					mResume = false;
					while (mResume == false) {
						try {
							join(100);
						} catch (InterruptedException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					break;
				} catch (IOException e) {
					Log.d(TAG, "==>  _COMPRESS222 : catch a IOException e");
					e.printStackTrace();
					targetFile.delete();
					onNoEnoughSpace();
					break;
				}
				break;
				
			case FileOp.FOP_DECOMPRESS:
				
//					String path = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH)+"/"  
//					+bundle.getString(FileOp.KEY_STRING_SRC_FILE_NAME);
					String path = bundle.getString(FileOp.KEY_STRING_SRC_FILE_PATH);
					if (bundle.getBoolean(FileOp.KEY_BOOLEAN_IS_ZIP)) {
						try{
							unzipFile(instance,path);
						}catch (Exception e) {
							Log.d(TAG,"==>  _DECOMPRESS ZIP : IO Exception 1");
							e.printStackTrace();
							StatFs sf = new StatFs(FileUtil.sdroot);
							if (((long) sf.getAvailableBlocks() * sf.getBlockSize()) < (long) 1024) {
								onNoEnoughSpace();
							} else {
								Log.d(TAG,"==> _DECOMPRESS ZIP : IO Exception 2");
								e.printStackTrace();
								Message msg = mEH.obtainMessage(UNZIP_EXCEPTION_MSG, 0,
										0, e.getMessage());
								mEH.sendMessage(msg);
								mResume = false;
								while (mResume == false) {
									try {
										join(100);
									} catch (InterruptedException e1) {
										// TODO Auto-generated catch block
										e1.printStackTrace();
									}
								}
							}
						}
						//unzipFile(bundle.getString("zipfile"));
					} else {
						// [improve] can not decompess
						// unrarFile(bundle.getString("zipfile"));
						String source= bundle.getString(FileOp.KEY_STRING_SRC_FILE_PATH);
//						String target=source.substring(0,path.length()-3);
						
//						decompressGzipFile(source, target);
					}
				break;
			default:
				break;
			}
			Log.d(TAG, "==> Thread exits ");
			mWakeLock.release();
						
//			FileCompressor.this.mProgress.dismiss();
//			FileCompressor.this.finish();
			Message msg;
			if (mStop) {
				msg = mEH.obtainMessage(MSG_RESULT_CANCELED, 0, 0, null);
			} else {
				
				if (FileOp.FOP_COMPRESS == requestCode && null != targetFile 
						&& targetFile.exists()){
					intent.putExtra("NEW_FILE", targetFile.getAbsolutePath());
				}else if (FileOp.FOP_DECOMPRESS == requestCode && mlNewFiles.size() > 0){
					intent.putStringArrayListExtra("NEW_FILES", mlNewFiles);
				}
				msg = mEH.obtainMessage(MSG_RESULT_OK, 0, 0, null);
			}
			mEH.sendMessage(msg);			
		}
		 
		 private void onNoEnoughSpace(){
				mStop = false;
				Message msg = mEH.obtainMessage(ZIP_NOSPACE_MSG, 0, 0, "");
				mEH.sendMessage(msg);
				
				mResume = false;
				while(mResume == false && mStop==false){
					try {
						join(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
		 }

		
		 public  void decompressGzipFile(String source ,String target)  {
			 File decompressedFile=new File(target);
			
			 
			 try{
				 if(!decompressedFile.exists()){
					 decompressedFile.createNewFile(); 
				 }
				 	
				 FileInputStream fin=new FileInputStream(source);  
				 GZIPInputStream gzin=new GZIPInputStream(fin);  
				 FileOutputStream fout=new FileOutputStream(target); 
				 byte[] buf=new byte[1024]; 
				 int num;
				 while ((num=gzin.read(buf,0,buf.length))!=-1) {
				 fout.write(buf,0,num); 
				 }
				 gzin.close(); 
				 fout.close();  
				 fin.close();  
				 
			 }catch (Exception ex){
				 	ex.printStackTrace();
				 	if(decompressedFile.exists()){
				 		decompressedFile.delete();
				 	}
				 	
					StatFs sf = new StatFs(FileUtil.sdroot);
					if (((long) sf.getAvailableBlocks() * sf.getBlockSize()) < (long) 1024) {
						onNoEnoughSpace();
					}else{
						mStop = false;
						Message msg = mEH.obtainMessage(INVALID_GZ_FILE_MSG, 0, 0, "");
						mEH.sendMessage(msg);	
						mResume = false;
						while(mResume == false && mStop==false){
							try {
								join(100);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					   return;
					}
				 	
			   
			 }
				
			
		 	
		 
	    }
		 
		public void zipFile(File resFile, MyZipOutputStream zipout, String rootpath) throws IOException {
			StatFs sf = new StatFs(FileUtil.sdroot);
			
			rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator) + resFile.getName();
			
			if (resFile.isDirectory()) {
				File[] fileList = resFile.listFiles();
				zipout.putNextEntry(new ZipEntry(rootpath + "/"));
				for (File file : fileList){
					zipFile(file, zipout, rootpath);
					//add 2010-12-07 by xqm
					 if (mStop)
                         break;
					 //end
				}
					

			} else {
				byte buffer[] = new byte[BUFF_SIZE];
				BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile), BUFF_SIZE);
				zipout.putNextEntry(new ZipEntry(rootpath));
				
				int realLength;
				while ((realLength = in.read(buffer)) != -1) {
					if (mStop) {
						cFile.delete();
						break;
					}
					// Log.i(TAG,"left space="+sf.getAvailableBlocks()*sf.getBlockSize());
					zipout.write(buffer, 0, realLength);
				}
				in.close();
				zipout.flush();
				zipout.closeEntry();
			}
		}	 
		 
		private void zipFiles(List<File> resFileList, File zipFile) throws IOException {
			BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE);
			MyZipOutputStream zipout = new MyZipOutputStream(buf, "GBK");
			
			StatFs sf = new StatFs(FileUtil.sdroot);
			for (File resFile : resFileList) {
				if (mStop) {
					zipout.close();
					// Log.d("wuqf",
					// "************ have canceled zip *********");
					cFile.delete();
					return;
				}

				// Long available =
				// Long.valueOf(sf.getAvailableBlocks()*sf.getBlockSize());
				if (((long) sf.getAvailableBlocks() * sf.getBlockSize()) < (long) 65536) {
					zipFile.delete();
					onNoEnoughSpace();
					break;
				}

				if (!resFile.getAbsolutePath()
						.equals(zipFile.getAbsolutePath())) {
					zipFile(resFile, zipout, "");
				} else {
					Log.d(TAG, "**********same file : "
							+ resFile.getAbsolutePath());
				}
			}

			if (!zip_nospace_flag) {
				zipout.close();
			}
		}
		 		 
		 private void unzipFile(Context context, String zipFileName) throws Exception {
				FileInputStream in = new FileInputStream(zipFileName);
				MyZipInputStream zipIn = new MyZipInputStream(in, "GBK");
				//MyZipInputStream zipIn = new MyZipInputStream(in);
				ZipEntry zipEntry = null;
				
				String strPath, strtemp;
				File f = new File(zipFileName);
				File tempFile = new File(f.getParent()); // dest dir
				strPath = tempFile.getAbsolutePath();
				
				StatFs sf;
			   sf = new StatFs(FileUtil.sdroot);
			   zipEntry = zipIn.getNextEntry();
			   if(zipEntry == null){
				   mStop = false;
					Message msg = mEH.obtainMessage(INVALID_ZIP_FILE_MSG, 0, 0, "");
					mEH.sendMessage(msg);
					
					mResume = false;
					while(mResume == false && mStop==false){
						try {
							join(100);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				   return;
			   }
			   
			   // clean new file list
			   mlNewFiles.clear();
			   
				while(zipEntry != null){
					if(mStop)
					{
						break;
					}
					mResume = true;
					mReplace = true;
					if(((long)sf.getAvailableBlocks()*sf.getBlockSize()) < (long)1024){
						Log.d(TAG, "==> zipEntry : no space");
				    	onNoEnoughSpace();
				    	break;
				    }
					
					strtemp = strPath + "/" + zipEntry.getName();	
					if(strtemp.equals(zipFileName)){
						Log.d(TAG, "==> same file: " + zipFileName);
						zipEntry = zipIn.getNextEntry();
						continue;
					}
					
					File file = new File(strtemp); // dest file
					if(file.exists()){
						if(zipEntry.isDirectory() && file.isDirectory()){
							zipEntry = zipIn.getNextEntry();
							continue;
						}
						
						// handle the case : same file existed
						//add bug 80525
						if (mForAll) {
							if(!mReplace){
								Log.d(TAG, "==> Doesn't  replace source file");
								zipEntry = zipIn.getNextEntry();
								continue;
							}
						}else{
							mResume = false;
							Message msg = mEH.obtainMessage(MSG_SAMEFILE_EXISTS_ON_UNZIP, 0, 0 , file.getName().trim());
							mEH.sendMessage(msg);
							while(mResume == false){
								 this.join(100);
							}

							if (mStop)
								break;
							
							if(!mReplace){
								Log.d(TAG, "==> Doesn't  replace source file");
								zipEntry = zipIn.getNextEntry();
								continue;
							}
						}	
						//end
				    }
				   
					if(zipEntry.isDirectory()){
						file.mkdir();
						Log.d(TAG, "==> zipEntry dir : " + zipEntry);
						

					}else{
						File parent = file.getParentFile();

						if(!parent.exists()){
						   parent.mkdirs();
						}
						
						/*
						 * add 2010-11-25 by xie
						 */
						if(mNeedBroadCastFileChanged == false){
							mNeedBroadCastFileChanged = neadBroadCast(strtemp);
							Log.d(TAG, "the mNeedBroadCastFileChanged is:" + mNeedBroadCastFileChanged);
						}
						//end
						
						Log.d(TAG, "==> decompressor file name :" + strtemp);
						FileOutputStream fileout = new FileOutputStream(file);
						byte buffer[] = new byte[BUFF_SIZE];
						int realLength = 0;
						while ((realLength = zipIn.read(buffer)) > 0) {
							if(mStop){
								file.delete();
								break;
							}
							fileout.write(buffer, 0, realLength);
						}
						fileout.close();
					}
					
					// update new file list
					if (file.getParentFile().equals(tempFile)){
						mlNewFiles.add(file.getAbsolutePath());
					}
					
					zipEntry = zipIn.getNextEntry();
					/*
					 * add 2010-11-25 by xie
					 */
					if (mNeedBroadCastFileChanged) {
						Log.d(TAG, "to send file changed broadcast: "
								+ tempFile.getAbsolutePath());
						sendBroadcast(new Intent(
								Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
										.fromFile(tempFile)));
						Log.d(TAG, "[notify mediascanner] unzip file");
						FileUtil.notifyMediaScanner(mContext, null);
					}
					//end
				}
				zipIn.closeEntry();	
			}
 
		 /*
		 private void unrarFile(String rarFileName) throws Exception {
			 	String strPath,strtemp;
			 	File rarfile = new File(rarFileName);
			 	File tempFile = new File(rarfile.getParent());
			 	strPath = tempFile.getAbsolutePath();
			 
			 	Archive a = null;
			 	try
			 	{
			 		a = new Archive(rarfile);
			 	}
			 	catch (RarException e)
			 	{
			 		e.printStackTrace();
			 	}
			 	catch (IOException e)
			 	{
			 		e.printStackTrace();
			 	}
				if(a != null)
				{
					a.getMainHeader().print();
					//Log.d("WEI~~TETS001", a.getMainHeader());
					FileHeader fh = a.nextFileHeader();
					while(fh != null)
					{
						try{
							strtemp = strPath + "/";
							File file = new File(strtemp + fh.getFileNameString().trim());
							if(file.exists()){
								if(fh.isDirectory() && file.isDirectory()){
									fh = a.nextFileHeader();
									//zipEntry = zipIn.getNextEntry();
									continue;
								}
								
								mResume = false;
								Message msg = mEH.obtainMessage(MSG_SAMEFILE_EXISTS_ON_UNZIP, 0, 0 , file.getName().trim());
								mEH.sendMessage(msg);
								while(mResume == false){
									 this.join(100);
								}
								
								if(!mReplace){
									//Log.d("wuqf", "********* Doesn't  replace source file *******");
									fh = a.nextFileHeader();
									continue;
								}
						    }

							if(fh.isDirectory()){
								file.mkdir();
								//Log.d("wuqf", "********* zipEntry dir : " + zipEntry);
							}else{

								File parent = file.getParentFile();

								if(!parent.exists()){
								   parent.mkdirs();
								}
								Log.d(TAG, file.getAbsolutePath());
								FileOutputStream os = new FileOutputStream(file);
								a.extractFile(fh,os);
								os.close();
							}
						} 
						catch (FileNotFoundException e)
						{
							e.printStackTrace();
						}catch (RarException e)
						{
							e.printStackTrace();
						}
						catch (IOException e)
						{
							e.printStackTrace();
						}
						fh = a.nextFileHeader();
					}
				}
			}
		 */
	}

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		instance = this;   //add 2010-11-25 by xie
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		
		Log.i(TAG, "==> onCreate !");
		intent = getIntent();
		bundle = intent.getExtras();
		
		if(null == bundle){
			finish();
			return;
		} 
					
		mProgress = new ProgressDialog(this);
		mProgress.setOnDismissListener(new OnDismissListener(){

			public void onDismiss(DialogInterface arg0) {
				// TODO Auto-generated method stub
				if(mThread != null){
					Log.d(TAG, "*********** to stop thread **************");
					mThread.toStop();
				}				
				//finish();
			}
			
		});

		//getDisplayMetrics();
		
	}

	/*private void getDisplayMetrics(){
		mdisplayMetric=new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(mdisplayMetric);
		Log.d(TAG,"height"+mdisplayMetric.heightPixels/2);
		Log.d(TAG, "wight"+mdisplayMetric.widthPixels/2);
	}*/
	
	private void quitWithResult(int result) {
	    setResult(result, intent);
	    finish();		
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		String path;
		if (runFlag == true){
			return;
		}
		requestCode = bundle.getInt(FileOp.KEY_INT_FOP_CODE);
		
		if (FileOp.FOP_DECOMPRESS == requestCode ){
					path = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH);
//					+"/"
//					+bundle.getString(FileOp.KEY_STRING_SRC_FILE_NAME);			
				
		}else if (FileOp.FOP_COMPRESS == requestCode){
				path = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH) + "/" 
				+ bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
		}else { 
			Log.e(TAG, "unknown request code in onResume");
			return;
		}
				
		String status = Environment.getExternalStorageState();
	    if (path.startsWith(FileUtil.sdroot) 
	    		|| status.equals(Environment.MEDIA_MOUNTED) 
	    		|| status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
	    	Log.d(TAG, "sdcard mounted!");
			switch (requestCode) {
			case FileOp.FOP_COMPRESS:
				String temp = bundle.getString(FileOp.KEY_STRING_DEST_DIR_PATH) + "/" 
				+ bundle.getString(FileOp.KEY_STRING_DEST_FILE_NAME);
	            Log.i(TAG, "==> onResume :the temp is"+temp);
	            
	            if (temp == null){
	    			Log.e(TAG, "the des file is null in onResume");
	    			quitWithResult(RESULT_CANCELED);
	            }else {
	            	// case: the des file is existed
		    		if (!(new File(temp)).exists()){
		    			doAction();
		    		}else {
		    			mDialogHandled = false;
		    			
		    			
		    			
		    			
		    			//MyTask();
						//mytimer.schedule(mytask, delay
						
		    			/*try{
		    				//mytimer.wait(100);
		    				//MyTask();
		    				Timer timer=new Timer();
		    				timer.schedule(new TimerTask (){
		    					public void run(){
		    						Message message=mMyHander.obtainMessage(EXIST_SAME_GZ_FILE);
		    						mMyHander.sendMessage(message);
		    						Log.d(TAG, "send message successfully !");
		    						
		    					}
		    					
		    				}, 50);
		    				
		    				
		    				
		    				
		    			}catch(Exception e){
		    				Log.d(TAG, "send message error !");
		    			}*/
		    			
		    			new AlertDialog.Builder(FileCompressor.this)
		    	        	.setTitle(R.string.remind)
		    	        	.setMessage(R.string.override)
		    	        	.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
		    	        		public void onClick(DialogInterface dialog, int whichButton) {
		    	        			mDialogHandled = true;
		    	        			doAction();
		    	        		}
		    	        	})
		    	        	.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
		    	        		public void onClick(DialogInterface dialog, int whichButton) {
		    	        			// User clicked cancel so do some stuff
		    	        			mDialogHandled = true;
		    	        			if(mThread != null)
		    	        				mThread.toStop();
		    	        			else{
		    	        				quitWithResult(RESULT_CANCELED);
		    	        			}
		    	        		}
		    	        	})
		    	        	.show().setOnDismissListener(new OnDismissListener(){
		    	        		public void onDismiss(DialogInterface arg0) {
		    					// TODO Auto-generated method stub
		    	        			if(mDialogHandled == false)
		    	        				quitWithResult(RESULT_CANCELED);
		    	        		}
		    	        	});
		    		}
	    		}			
				break;
				
			case FileOp.FOP_DECOMPRESS:
				
				if(bundle.getBoolean(FileOp.KEY_BOOLEAN_IS_ZIP)){
					doAction();
				}else{
					String dir=path.substring(0,path.length()-3);
					Log.d(TAG, "gz:dir="+dir);	
		    					
		   				try{	   					
				    		File fileTarget=new File(dir);
				    		   if(!fileTarget.exists()){
				    			   fileTarget.createNewFile();
				    			   //Log.v("hello world!", "target file not exist!");
				    			   doAction();
				    		   }else{/*
				    			   
				    			   Timer timer=new Timer();
				    			   timer.schedule(new TimerTask (){
				    				   public void run(){
				    					   Message message=mMyHander.obtainMessage(MY_MSG);
				    					   mMyHander.sendMessage(message);
				    					   Log.v(TAG, "send message successfully !");
		       						
				    				   	}
		       					
				    			   	}, 50);
		       				
				    		   */
				    				new AlertDialog.Builder(FileCompressor.this)
				    	        	.setTitle(R.string.remind)
				    	        	.setMessage(R.string.override)
				    	        	.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
				    	        		public void onClick(DialogInterface dialog, int whichButton) {
				    	        			mDialogHandled = true;
				    	        			doAction();
				    	        		}
				    	        	})
				    	        	.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
				    	        		public void onClick(DialogInterface dialog, int whichButton) {
				    	        			// User clicked cancel so do some stuff
				    	        			mDialogHandled = true;
				    	        			if(mThread != null)
				    	        				mThread.toStop();
				    	        			else{
				    	        				quitWithResult(RESULT_CANCELED);
				    	        			}
				    	        		}
				    	        	})
				    	        	.show().setOnDismissListener(new OnDismissListener(){
				    	        		public void onDismiss(DialogInterface arg0) {
				    					// TODO Auto-generated method stub
				    	        			if(mDialogHandled == false)
				    	        				quitWithResult(RESULT_CANCELED);
				    	        		}
				    	        	});   
				    		   
				    		   }
		       				
		       				
		       			}catch(Exception e){
		       				Log.d(TAG, "send message error !");
		       			}
					
					
				}

				
				break;
	
			default:
				break;
			}
	    }else{
	    	
	 	   

			   
	    	
	    	
	    	new AlertDialog.Builder(FileCompressor.this)
            //.setIcon(R.drawable.FileCompressor)
            	.setTitle(R.string.remind)
            	.setMessage(R.string.sdunavailable)
            	.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
            		public void onClick(DialogInterface dialog, int whichButton) {
            			if(mThread != null){
            				mThread.toStop();
            			}else{
            				quitWithResult(RESULT_CANCELED);
            			}
            		}
            	}).show();
	    }
	}	
	
	public void delFilePath(File cFile2) {
		// TODO Auto-generated method stub
		File[] child = cFile2.listFiles();
		if((child != null) && (child.length != 0))
		{
			int j = child.length;
			for(int i = 0; i < j; i++)
			{
				if(child[i].isDirectory())
				{
					delFilePath(child[i]);
				}
				else
				{
					child[i].delete();
				}
			}
		}
	}

	/*
	 * add 2010-11-25 by xie
	 */
	private boolean neadBroadCast(String sFileName){
		File file = new File(sFileName);
		if(file.isDirectory())
			return false;
		
		String sTemp = sFileName.toLowerCase();
		if(mMimeTypes == null)
			initMimeTypes();
		
		String type = mMimeTypes.getMimeType(sTemp);
		if(type != null){ 
			if(type.startsWith("image") || type.startsWith("audio") || type.startsWith("video")){
				return true;
			}
		}
		
		return false;
	}
	
	private void initMimeTypes() {
    	if(mMimeTypes == null){
   	   MimeTypeParser mtp = new MimeTypeParser();

//   	   XmlResourceParser in = getResources().getXml(com.android.internal.R.xml.mimetypes);
   	   XmlResourceParser in = getResources().getXml(R.xml.mimetypes);

   	   try {
   		   mMimeTypes = mtp.fromXmlResource(in);
   	   } catch (XmlPullParserException e) {
   		   Log.e(TAG,"PreselectedChannelsActivity: XmlPullParserException",e);
   		   throw new RuntimeException("PreselectedChannelsActivity: XmlPullParserException");
   	   } catch (IOException e) {
   		   Log.e(TAG, "PreselectedChannelsActivity: IOException", e);
   		   throw new RuntimeException("PreselectedChannelsActivity: IOException");
   	        }
    	}
    }
	//end
	
	private void doAction(){
    	mThread = new ZipThread(FileCompressor.this);
    	   	
    	filelist = (List<File>) bundle.getSerializable("filelist");
    	
		if (requestCode == FileOp.FOP_COMPRESS) {
			mProgress.setMessage(getString(R.string.waiting_compressing));
			mProgress.setTitle(R.string.alert_dialog_compress);			
		}else if (requestCode == FileOp.FOP_DECOMPRESS) {
			mProgress.setMessage(getString(R.string.waiting_decompressing));
			mProgress.setTitle(R.string.alert_dialog_decompress);
		}
		
		mProgress.setButton(getString(R.string.cancle), new ProgressDialog.OnClickListener() {
			public void onClick(final DialogInterface dialog, final int which) {
				// TODO Auto-generated method stub
				Log.v("TAG", "==>tankx t.stop()");
				mThread.toStop();
			}});		
		mProgress.show();
		
		mThread.start();
	}
	

}
